Add make_bstr*(std::wstring_view)#634
Conversation
| #if defined(__WIL_OLEAUTO_H_) | ||
| #if defined(_STRING_VIEW_) || defined(__cpp_lib_string_view) | ||
| // Create wil::unique_bstr from std::wstring_view (regardless if not null terminated, or if it contains embedded nulls) | ||
| inline wil::unique_bstr make_bstr_nothrow(std::wstring_view source) noexcept |
There was a problem hiding this comment.
For bonus points - there is also the wil::zwstring_view overloads that enforce null termination but are ortherwise just a string_view.
There was a problem hiding this comment.
Can basic_zstring_view decay to basic_string_view? Or is there something special preventing object slicing?
There was a problem hiding this comment.
It might. I didn't actually check and just assumed a specialization would be needed.
| } | ||
| inline wil::unique_bstr make_bstr_failfast(std::wstring_view source) noexcept | ||
| { | ||
| return wil::unique_bstr(FAIL_FAST_IF_NULL_ALLOC(::SysAllocStringLen(source.data(), static_cast<UINT>(source.size())))); |
There was a problem hiding this comment.
Consider implementing this in terms of the nothrow variant, rather than repeating it here.
| } | ||
|
|
||
| #if defined(__WIL_OLEAUTO_H_) | ||
| #if defined(_STRING_VIEW_) || defined(__cpp_lib_string_view) |
There was a problem hiding this comment.
In the general case, this is a problematic check because <version> also defines __cpp_lib_string_view even though <string_view> may not have been included. That said, this is the stl.h header, so it already (1) assumes STL use and (2) already includes <string_view> with the correct guards, so this concern is moot, but it does make the _STRING_VIEW_ check unnecessary. Better yet if you compare to a specific release. E.g. this could ideally become:
| #if defined(_STRING_VIEW_) || defined(__cpp_lib_string_view) | |
| #if __cpp_lib_string_view >= 201606L |
... which means you can just move this definition a few lines lower since this check is already present.
| return str.c_str(); | ||
| } | ||
|
|
||
| #if defined(__WIL_OLEAUTO_H_) |
There was a problem hiding this comment.
stl.h is not like resource.h and cannot be included multiple times to pick up new definitions, so this will be fragile and subject to include order dependencies. That said, trying to put this in resource.h may not be the best option either. In theory, there could be a _STRING_VIEW_ check, however I'm not a fan of these since (1) this is an implementation detail and might change, (2) might break if someone uses something other than the MSVC STL, and (3) isn't compatible with modules. We could also add a conditional include such as:
#if WIL_USE_STL && (__WI_LIBCPP_STD_VER >= 17) && WI_HAS_INCLUDE(<string_view>, 1)
#include <string_view>
#endifand then later
#if WIL_USE_STL && (__cpp_lib_string_view >= 201606L)
// definition goes here
#endifwhich eliminates the "is string_view included already" check (the purpose of WIL_USE_STL), however given how widely used resource.h is used, the probability of unintentional side effects is high.
Another option is to add a function to resource.h that accepts a template argument that is constrained on is_string_view_like , so you don't have to bother with proper guards.
WIL only provides only PCWSTR overloads:
This PR adds
wstring_viewoverloads callingSysAllocStringLenwith the view's data and size directly, correctly handling non-null-terminated string viewsThis works for non-null-terminated views (substrings, slices), avoids unnecessary and dangerous wcslen walk (we know the wstring_view's length), and is a strict superset of the existing API.
NOTE: A
PCWSTRimplicitly converts towstring_view, so these new overloads could replace the existing ones once C++17 is the floor. WIL still supports older standards, so these additional overloads is safer.